﻿//  Copyright (c) 2011 Ray Liang (http://www.dotnetage.com)
//  Dual licensed under the MIT and GPL licenses:
//  http://www.opensource.org/licenses/mit-license.php
//  http://www.gnu.org/licenses/gpl.html

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using DNA.Mvc.jQuery;
using System.Web.Mvc;

namespace DNA.Mvc.jQuery
{
    public abstract class ComboBoxBuilder<TModel,TBuilder> : DataListBuilder<TModel, ComboBox<TModel>, ComboBoxOptions, TBuilder>
        where TModel : class
        where TBuilder : ComboBoxBuilder<TModel, TBuilder>
    {
        // private Action _templ;

        protected override string jQueryPluginName
        {
            get { return "combo"; }
        }

        public ComboBoxBuilder(ComboBox<TModel> component, ViewContext viewContext, IViewDataContainer viewContainer) :
            base(component, viewContext, viewContainer) { }

        /// <summary>
        /// Change ComboBox dropdown style.
        /// </summary>
        /// <param name="style"></param>
        /// <returns></returns>
        public TBuilder DropDownStyle(DropdownStyles style)
        {
            Options(opts => { opts.DropDownStyle = style; });
            return this as TBuilder;
        }

        public TBuilder DropDownList()
        {
            return this.DropDownStyle(DropdownStyles.DropdownList);
        }

        /// <summary>
        /// Set custom dropdown content template for ASPX
        /// </summary>
        /// <param name="template"></param>
        /// <returns></returns>
        public TBuilder DropDownContent(Action template)
        {
            Component.DropDownTemplate.Content = template;
            return this as TBuilder;
        }

        /// <summary>
        /// Set custom dropdown content template for Razor
        /// </summary>
        /// <param name="template"></param>
        /// <returns></returns>
        public TBuilder DropDownContent(Func<object, object> template)
        {
            Component.DropDownTemplate.InlineContent = template;
            return this as TBuilder;
        }

        /// <summary>
        /// Set selected value.
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public TBuilder Select(string value)
        {
            Options(opts => { opts.SelectedValue = value; });
            return this as TBuilder;
        }
        
        public override void Render()
        {
            _PreRender();
            base.Render();
        }
        
        public override MvcHtmlString GetHtml()
        {
            _PreRender();
            return base.GetHtml();
        }

        private void _PreRender()
        {
            if (string.IsNullOrEmpty(Component.RemoteDataSource))
            {
                //if ((Component.Items.Count > 0) || (!Component.DropDownTemplate.IsEmpty))
                    Options(opts =>
                    {
                        opts.Source = "$('#" + Component.Id + "_menu')";
                    });
            }
        }

        protected override void OnRemoteDataBind(HtmlTextWriter writer)
        {
            var opts = new jQueryScriptBuilder("#" + Component.Id, jQueryPluginName);
            Options(options =>
            {
                options.ItemTemplateID = Component.Id + "_tmpl";
                options.ParticalLoad = true;
                options.Source = string.Empty;
                opts.AddOptions(options);
            });
            opts.AddOption("source", Component.RemoteDataSource, true);
            RenderComponent(writer);
            Helper.RegisterStartupScript(opts.ToString());
        }
    }

    public class ComboBoxBuilder<TModel> : ComboBoxBuilder<TModel, ComboBoxBuilder<TModel>>
        where TModel:class
    {
        public ComboBoxBuilder(ComboBox<TModel> component, ViewContext viewContext, IViewDataContainer viewContainer) :
            base(component, viewContext, viewContainer) { }
    }

    public class ComboBoxBuilder : ComboBoxBuilder<INavigable, ComboBoxBuilder>
    {
        public ComboBoxBuilder(ComboBox<INavigable> combo, ViewContext viewContext, IViewDataContainer viewContainer) :
            base(combo, viewContext, viewContainer) { }

        /// <summary>
        /// Bind Enum to Combo
        /// </summary>
        /// <param name="_enum"></param>
        /// <returns></returns>
        public ComboBoxBuilder Bind(Enum _enum)
        {
            string[] names = Enum.GetNames(_enum.GetType());
            var _list = new List<NavigableData>();

            for (int i = 0; i < names.Length; i++)
            {
                _list.Add(new NavigableData()
                {
                    Title = names[i],
                    Value = names[i]
                });
            }
            // Options(opts => { opts.SelectedValue = _enum.ToString(); });
            return Bind(_list) as ComboBoxBuilder;
        }

        /// <summary>
        /// Bind string array to Combo
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public ComboBoxBuilder Bind(string[] values)
        {
            var _list = new List<NavigableData>();
            for (int i = 0; i < values.Length; i++)
            {
                _list.Add(new NavigableData()
                {
                    Title = values[i],
                    Value = values[i]
                });
            }
            return Bind(_list) as ComboBoxBuilder;
        }
    }
}
